Obsidian 読書ログのマンスリービュー 2
< Obsidian 1ヶ月の間に読んだ本をカレンダーのマンスリービューで表示する || Obsidian 読書記録マンスリービュー 3 >
2024-10-08 前の月、次の月ボタンが機能しない問題を解消
関連: Obsidian TC マンスリービュー
code:dataviewjs.js
`dataviewjs
// 現在の年月を取得
let today = new Date();
let year = today.getFullYear();
let month = today.getMonth(); // JavaScriptの月は0が1月、11が12月
// カレンダーを生成する関数
async function generateCalendar(year, month) {
const specifiedMonth = window.moment(year, month); // 指定された月
const firstDayOfMonth = specifiedMonth.startOf('month');
const daysInMonth = specifiedMonth.daysInMonth();
const fs = app.vault.adapter; // ObsidianのファイルシステムにアクセスするためのAPI
// カレンダーテーブルのスタイルを設定
let calendarHTML = `
<style>
table.calendar {
width: 100%;
table-layout: fixed; /* 列幅を均一に */
}
table.calendar th, table.calendar td {
padding: 5px;
text-align: center;
vertical-align: top;
}
table.calendar td {
height: 100px; /* セルの高さを統一 */
}
.nav-button {
margin: 10px;
cursor: pointer;
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.book-list {
text-align: left; /* 書籍名を左寄せ */
font-size: 10px; /* 書籍名のフォントサイズを小さく */
}
.book-list div {
margin-bottom: 3px; /* 書籍名同士のマージンを広く */
}
.calendar-day {
color: gray; /* 日付をグレーに */
font-size: 12px; /* 日付のフォントサイズを小さく */
margin-bottom: 8px; /* 日付と書籍名の間のマージンを広く */
display: block; /* ブロック要素として扱い、マージンを適用 */
}
.calendar-weekday {
color: gray; /* 曜日をグレーに */
font-size: 12px; /* 曜日のフォントサイズを小さく */
}
/* 曜日ヘッダーのスタイルを強制的に適用 */
table.calendar th.calendar-weekday {
color: gray;
font-size: 12px;
}
</style>
<div class="calendar-header">
<h2>${year}年 ${specifiedMonth.format('M')}月</h2>
<div>
<button class="nav-button" id="prevMonth">< 前の月</button>
<button class="nav-button" id="nextMonth">次の月 ></button>
</div>
</div>
<table class="calendar" border="1">
`;
// 曜日のヘッダーを作成
calendarHTML += `<tr>
<th class="calendar-weekday">Sun</th>
<th class="calendar-weekday">Mon</th>
<th class="calendar-weekday">Tue</th>
<th class="calendar-weekday">Wed</th>
<th class="calendar-weekday">Thu</th>
<th class="calendar-weekday">Fri</th>
<th class="calendar-weekday">Sat</th>
</tr><tr>`;
// 月の最初の日の曜日を取得して、空白セルを追加
let firstDayWeekday = firstDayOfMonth.day();
for (let i = 0; i < firstDayWeekday; i++) {
calendarHTML += <td></td>;
}
// 日付ごとにループし、データを取得
for (let day = 1; day <= daysInMonth; day++) {
const dateString = specifiedMonth.clone().startOf('month').add(day - 1, 'days').format('YYYY-MM-DD');
const filePath = notes/${dateString}.md; // デイリーノートが保存されているパス
// 書籍名を格納する変数 (重複削除のためSetを使用)
let booksForDay = new Set();
if (await fs.exists(filePath)) { // ファイルが存在するか確認
const fileContent = await dv.io.load(filePath); // ファイルの内容を取得
const lines = fileContent.split('\n');
// 各行をチェックし、書籍名があるかを確認
lines.forEach(line => {
const match = line.match(/『(.*?)』/);
if (match) {
booksForDay.add(match1); // Setを使って重複を自動的に削除
}
});
// 書籍名がある場合、左寄せで表示し、前に「・」を追加
if (booksForDay.size > 0) {
calendarHTML += <td><strong class="calendar-day">${day}</strong><div class="book-list">;
booksForDay.forEach(book => {
calendarHTML += <div>・${book}</div>; // 書籍名の前に「・」を追加して表示
});
calendarHTML += </div></td>;
} else {
// 書籍名がない場合、日付のみを表示
calendarHTML += <td><strong class="calendar-day">${day}</strong></td>;
}
} else {
// ファイルが存在しない場合、日付のみを表示
calendarHTML += <td><strong class="calendar-day">${day}</strong></td>;
}
// 土曜日ごとに行を終了し、次の行を開始
if ((day + firstDayWeekday) % 7 === 0) {
calendarHTML += </tr><tr>;
}
}
// カレンダーの最後に空白セルを追加して整える
let lastDayWeekday = (firstDayWeekday + daysInMonth) % 7;
if (lastDayWeekday !== 0) {
for (let i = lastDayWeekday; i < 7; i++) {
calendarHTML += <td></td>;
}
}
calendarHTML += </tr></table>;
// カレンダーを表示
dv.container.innerHTML = calendarHTML;
}
// 初期表示のカレンダーを生成
generateCalendar(year, month);
// 前の月、次の月に移動するボタンのイベントリスナーを追加
document.addEventListener("click", function (event) {
if (event.target && event.target.id === "prevMonth") {
month--;
if (month < 0) {
month = 11;
year--;
}
generateCalendar(year, month); // カレンダーを再生成
}
if (event.target && event.target.id === "nextMonth") {
month++;
if (month > 11) {
month = 0;
year++;
}
generateCalendar(year, month); // カレンダーを再生成
}
});
`